const { fetchRepoList, fetchTagList } = require("./request")
const Inquirer = require('inquirer') // 用户选择模块
const ora = require('ora') // 加载loading效果 
const downloadGitRepo = require('download-git-repo') // 根据repo和tag下载github中的文件 不支持promise
const path = require('path')

const util = require('util')

async function sleep (n) { // 延迟函数
  return new Promise(resolve => setTimeout(resolve, n))
}

async function warpLoading (fn, msg, ...args) { // 等待loading
  const spinner = ora(msg)
  spinner.start() // 开启加载


  try {
    let repos = await fn(...args)
    spinner.succeed()
    return repos
  } catch (error) {
    spinner.fail('request failed, refetch....')
    await sleep(1000) // 如果拉取失败  延迟1秒再次拉取
    return warpLoading(fn, msg, ...args)
  }



}

class Creater {
  constructor(projectName, options) { // new 时调用构造函数
    // console.log('creactjs-----', projectName, options, cwd)
    this.name = projectName
    this.target = options
    this.downloadGitRepo = util.promisify(downloadGitRepo) // 将这个方法转化成promise
  }

  async create () { // 真实开始创建
    /*
     * 采用远程拉去的方式   github
     * 1.先去拉去当前组织下的模板
     * 2.再通过模板找到版本号
     * 3.下载
     */
    let repo = await this.fetchRepo()
    let tag = await this.fetchTag(repo)
    let downloadUrl = await this.download(repo, tag)
  }
  async fetchRepo () {
    // 失败要重新拉取

    let repos = await warpLoading(fetchRepoList, 'waiting fetch temlplate')
    if (!repos) return
    repos = repos.map(item => item.name)

    let { repo } = await Inquirer.prompt({
      name: 'repo',
      type: 'list',
      choices: repos,
      message: `please choices a template to create project`
    })
    return repo
  }

  async fetchTag (repo) {
    let tags = await warpLoading(fetchTagList, 'waiting fetch tag', repo)
    if (!tags) return
    tags = tags.map(item => item.name)
    let { tag } = await Inquirer.prompt({
      name: 'tag',
      type: 'list',
      choices: tags,
      message: `please choices a tag to create project`
    })
    return tag
  }

  async download (repo, tag) {
    /**
     * 1.拼接下载路径
     * 2.把资源下载到指定路径上 (可以增加缓存功能,例如下载到系统目录中  然后使用ejs handlerbar 去渲染模板  最后生成结果  再写入)
     * */

    let requestUrl = `zhu-cli/${repo}${tag ? '#' + tag : ''}`
    // await this.downloadGitRepo(requestUrl, path.resolve(process.cwd(), this.name))
    await warpLoading(this.downloadGitRepo, 'waiting download....', requestUrl, path.resolve(process.cwd(), this.name))
    return this.target
  }
}

module.exports = Creater